<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover" />
	<title>_Promise</title>
</head>
<body>
<script>
class _Promise {
	static PENDING = 'pending'
	static FULFILLED = 'fulfilled'
	static REJECTED = 'rejected'

	constructor(callback) {
		this.state = _Promise.PENDING;
		this.result = undefined;
		this.tasks = [];
		if (typeof callback === 'function') {
			callback(this.resolve.bind(this), this.reject.bind(this));
		}
	}

	resolve(result) {
		if (this.state !== _Promise.PENDING) return;
		this.state = _Promise.FULFILLED;
		this.result = result
		for (let task of this.tasks) {
			task.onSuccess(this.result);
		}
	}

	reject(result) {
		if (this.state !== _Promise.PENDING) return;
		this.state = _Promise.REJECTED;
		this.result = result
		for (let task of this.tasks) {
			task.onFail(this.result);
		}
	}

	then(onSuccess, onFail) {
		return new _Promise((resolve, reject) => {
			if (this.state === _Promise.FULFILLED) { // 成功
				setTimeout(() => {
					const result = typeof onSuccess === 'function' && onSuccess(this.result)
					resolve(result);
				}, 0)
			}
			if (this.state === _Promise.REJECTED) { // 失败
				setTimeout(() => {
					const result = typeof onFail === 'function' && onFail(this.result)
					resolve(result);
				}, 0)
			}
			if (this.state === _Promise.PENDING) { // 等待
				this.tasks.push({
					onSuccess: (val) => {
						const result = typeof onSuccess === 'function' && onSuccess(val)
						resolve(result);
					},
					onFail   : (val) => {
						const result = typeof onFail === 'function' && onFail(val)
						resolve(result);
					}
				})
			}
		})
	}
}


console.log(
	new _Promise((resolve, reject) => {
		console.log(`constructor---`)
		setTimeout(() => {
			reject(1);
		}, 2000)
	}).then(
		res => { console.log(`res---`, res) },
		err => {
			console.log(`err---`, err)
			return 2
		}
	).then(
		res => { console.log(`输出`, res) },
		() => { console.log(`报错`) }
	)
)

// console.log(
// 	new _Promise((resolve, reject) => {
// 		resolve(1)
// 		reject(2)
// 	})
// )


</script>
</body>
</html>
